package controllers;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.event.AjaxBehaviorEvent;

import beans.LogSearchBeanRemote;
import dto.DateDTO;
import dto.ServerLogEntryDTO;
/**
 * 
 * @author Zsombor
 *
 */
@ManagedBean
public class DateDTOController {

	@EJB
	LogSearchBeanRemote cb;

	@ManagedProperty(value = "#{date}")
	DateDTO date;

	@ManagedProperty(value = "#{date2}")
	DateDTO date2;

	private List<ServerLogEntryDTO> result;
	private Boolean show = false;
	private Boolean errshow = false;

	private ArrayList<String> day1 = new ArrayList<String>();
	private ArrayList<String> month1 = new ArrayList<String>();
	private ArrayList<String> year1 = new ArrayList<String>();

	private ArrayList<String> day2 = new ArrayList<String>();
	private ArrayList<String> month2 = new ArrayList<String>();
	private ArrayList<String> year2 = new ArrayList<String>();
	private boolean sortAscending = false; 
	private boolean showSenderIcon = false;
	private boolean showIdIcon = false;

	/**
	 * Description: default constructor
	 * @author Zsolt
	 */
	public DateDTOController() {
		initDates();
	}

	/**
	 * @Description: Listener that listen for all events coming from the left side -> modifies the right side
	 * @author Zsolt
	 * @param event
	 */
	public void leftListener(AjaxBehaviorEvent event) {
		initDates();
		setLeftSide();
	}
	
	/**
	 * @Description: Listener that listen for all events coming from the right side -> modifies the right side
	 * @author Zsolt
	 * @param event
	 */
	public void rightListener(AjaxBehaviorEvent event) {
		initDates();
		setRightSide();
	}
	
	/**
	 * @Description: Initialization of all Calendar elements
	 * @author Zsolt
	 */
	public void initDates() {
		day1.clear();
		day2.clear();
		month1.clear();
		month2.clear();
		year1.clear();
		year2.clear();
		for (int i = 1; i <= 31; i++) {
			day1.add(Integer.toString(i));
		}
		for (int i = 1; i <= 12; i++) {
			month1.add(Integer.toString(i));
		}
		for (int i = 2000; i <= Calendar.getInstance().get(Calendar.YEAR); i++) {
			year1.add(Integer.toString(i));
		}

		for (int i = 1; i <= 31; i++) {
			day2.add(Integer.toString(i));
		}
		for (int i = 1; i <= 12; i++) {
			month2.add(Integer.toString(i));
		}
		for (int i = 2000; i <= 2012; i++) {
			year2.add(Integer.toString(i));
		}
	}

	/**
	 * @Description: Method that returns true if year is leap
	 * @author Zsolt
	 * @param int -> year
	 * @return boolean
	 */
	public static boolean isLeapYear(int year) {
		if (year % 4 != 0) {
			return false;
		} else if (year % 400 == 0) {
			return true;
		} else if (year % 100 == 0) {
			return false;
		} else {
			return true;
		}
	}

	/**
	 * @Description: Method that actually changes right side caused by event from left side
	 * @author Zsolt
	 */
	public void setLeftSide() {
		for (int i = 2000; i < date.getYear(); i++) {
			year2.remove(Integer.toString(i));
		}
		date2.setYear(date.getYear());
		for (int i = 1; i < date.getMonth(); i++) {
			month2.remove(Integer.toString(i));
		}
		date2.setMonth(date.getMonth());
		for (int i = 1; i < date.getDay(); i++) {
			day2.remove(Integer.toString(i));
		}
		if (date.getMonth() == 2 || date.getMonth() == 4
				|| date.getMonth() == 6 || date.getMonth() == 9
				|| date.getMonth() == 11) {
			day2.remove(Integer.toString(31));
			day1.remove(Integer.toString(31));
		}
		if (date.getMonth() == 2) {
			day2.remove(Integer.toString(30));
			day1.remove(Integer.toString(30));
			if (!isLeapYear(date.getYear())) {
				day2.remove(Integer.toString(29));
				day1.remove(Integer.toString(29));
			}
		}
		date2.setDay(date.getDay());
	}

	/**
	 * @Description: Method that actually changes right side caused by event from right side
	 * @author Zsolt
	 */
	public void setRightSide() {
		for (int i = 2000; i < date.getYear(); i++) {
			year2.remove(Integer.toString(i));
		}
		if (date.getYear() == date2.getYear()) {
			for (int i = 1; i < date.getMonth(); i++) {
				month2.remove(Integer.toString(i));
			}
			if (date.getMonth() == date2.getMonth()) {
				for (int i = 1; i < date.getDay(); i++) {
					day2.remove(Integer.toString(i));
				}
			}
		}
		if (date.getMonth() == 2 || date.getMonth() == 4
				|| date.getMonth() == 6 || date.getMonth() == 9
				|| date.getMonth() == 11) {
			day2.remove(Integer.toString(31));
			day1.remove(Integer.toString(31));
		}
		if (date.getMonth() == 2) {
			day2.remove(Integer.toString(30));
			day1.remove(Integer.toString(30));
			if (!isLeapYear(date2.getYear())) {
				day2.remove(Integer.toString(29));
			}
		}
	}
	
	public String printDate() {
		result = cb.queryByDate(date, date2);
		if (result.isEmpty()) {
			show = false;
			errshow = true;
		} else {
			show = true;
			errshow = false;
		}
		return "ok";
	}

	public List<ServerLogEntryDTO> getResult() {
		return result;
	}

	public void setResult(List<ServerLogEntryDTO> result) {
		this.result = result;
	}

	public Boolean getShow() {
		return show;
	}

	public void setShow(Boolean show) {
		this.show = show;
	}

	public DateDTO getDate2() {
		return date2;
	}

	public void setDate2(DateDTO date2) {
		this.date2 = date2;
	}

	public DateDTO getDate() {
		return date;
	}

	public void setDate(DateDTO date) {
		this.date = date;
	}

	public Boolean getErrshow() {
		return errshow;
	}

	public void setErrshow(Boolean errshow) {
		this.errshow = errshow;
	}

	public ArrayList<String> getDay1() {
		return day1;
	}

	public void setDay1(ArrayList<String> day1) {
		this.day1 = day1;
	}

	public ArrayList<String> getMonth1() {
		return month1;
	}

	public void setMonth1(ArrayList<String> month1) {
		this.month1 = month1;
	}

	public ArrayList<String> getYear1() {
		return year1;
	}

	public void setYear1(ArrayList<String> year1) {
		this.year1 = year1;
	}

	public ArrayList<String> getDay2() {

		return day2;
	}

	public void setDay2(ArrayList<String> day2) {
		this.day2 = day2;
	}

	public ArrayList<String> getMonth2() {

		return month2;
	}

	public void setMonth2(ArrayList<String> month2) {
		this.month2 = month2;
	}

	public ArrayList<String> getYear2() {
		return year2;
	}

	public void setYear2(ArrayList<String> year2) {
		this.year2 = year2;
	}

	public boolean isSortAscending() {
		return sortAscending;
	}

	public void setSortAscending(boolean sortAscending) {
		this.sortAscending = sortAscending;
	}
	
	public String sortBySender() {
		 
		   if(sortAscending){
	 
			//ascending order
			Collections.sort(result, new Comparator<ServerLogEntryDTO>() {
	 
				@Override
				public int compare(ServerLogEntryDTO slo1, ServerLogEntryDTO slo2) {
	 
					return slo1.getSender().compareTo(slo2.getSender());
	 
				}
	 
			});
			showIdIcon =false;
			showSenderIcon = true;
			sortAscending = false;
	 
		   }else{
	 
			//descending order
			Collections.sort(result, new Comparator<ServerLogEntryDTO>() {
	 
				@Override
				public int compare(ServerLogEntryDTO slo1, ServerLogEntryDTO slo2) {
	 
					return slo2.getSender().compareTo(slo1.getSender());
	 
				}
	 
			});
			showIdIcon =false;
			showSenderIcon = true;
			sortAscending = true;
		   }
	 
		   return null;
		}
	
	public String sortById() {
		 
		   if(sortAscending){
	 
			//ascending order
			Collections.sort(result, new Comparator<ServerLogEntryDTO>() {
	 
				@Override
				public int compare(ServerLogEntryDTO slo1, ServerLogEntryDTO slo2) {
	 
					return slo1.getId().compareTo(slo2.getId());
	 
				}
	 
			});
			showIdIcon = true;
			showSenderIcon = false;
			sortAscending = false;
	 
		   }else{
	 
			//descending order
			Collections.sort(result, new Comparator<ServerLogEntryDTO>() {
	 
				@Override
				public int compare(ServerLogEntryDTO slo1, ServerLogEntryDTO slo2) {
	 
					return slo2.getId().compareTo(slo1.getId());
	 
				}
	 
			});
			showIdIcon = true;
			showSenderIcon = false;
			sortAscending = true;
		   }
	 
		   return null;
		}

	public boolean isShowSenderIcon() {
		return showSenderIcon;
	}

	public void setShowSenderIcon(boolean showSenderIcon) {
		this.showSenderIcon = showSenderIcon;
	}

	public boolean isShowIdIcon() {
		return showIdIcon;
	}

	public void setShowIdIcon(boolean showIdIcon) {
		this.showIdIcon = showIdIcon;
	}
}
